﻿using Kalman;
using Kalman.Data;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http.Features;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace QuDao.Api.Controllers
{
#pragma warning disable CA1041 // 不显示在swagger文档中
    [Obsolete]
#pragma warning restore CA1041 
    [ApiController]
    public class ErrorController : ControllerBase
    {
        [Route("/error-local-development")]
        public IActionResult ErrorLocalDevelopment([FromServices] IWebHostEnvironment env)
        {
            if (env.EnvironmentName != "Development")
            {
                throw new InvalidOperationException("不能在非开发环境中执行该操作");
            }

            var result = HandleError(true);
            return result;
        }

        [Route("/error")]
        public IActionResult Error()
        {
            var result = HandleError();
            return result;
        }

        /*
         * 错误代码定义（参考HTTP状态码）
         * 200      请求成功
         * 4XX      客户端请求错误
         * 400      无效的请求（客户端请求失败默认错误码）
         * 401      API认证失败（未授权或令牌过期）
         * 403      拒绝访问（没有访问资源的权限）
         * 404      未找到请求资源（请求数据不存在）
         * 5XX      服务端内部错误
         * 500      服务端默认错误码
         * 503      服务端超负载，无法处理请求
         * 
         * 返回数据说明
         * code     错误码
         * msg      错误消息，可以直接展示给用户
         * error    错误详情，仅在开发环境使用
         * data     接口返回数据
         */

        IActionResult HandleError(bool isDevelopment = true)
        {
            var feature = HttpContext.Features.Get<IExceptionHandlerFeature>();
            var log = LogManager.GetCurrentClassLogger();
            var ex = feature.Error;
            var code = 500;
            var msg = ex.Message;

            //if (ex.InnerException != null) msg = $"{msg}=>{ex.InnerException.Message}";

            var sb = new StringBuilder(msg);
            if (ex is AppException appException)
            {
                if (appException.InnerException == null)
                {
                    code = 400;//包装了内部异常表示是服务器内部异常
                }
                else
                {
                    var errorCode = appException.ErrorCode; //可能需要处理具体的4XX状态码，用于区分具体的客户端请求错误类型
                    if (!string.IsNullOrEmpty(errorCode) && errorCode.Length >= 3 && errorCode[0] == '4')
                    {
                        var statusCode = ConvertUtil.ToInt32(appException.ErrorCode[..3], 0);//例如：400-xxxxxxxxx
                        if (statusCode > 0) code = statusCode;
                    }
                }
            }
            else if (ex is ApiException apiException)
            {
                code = 400; //Api异常对象主要用来处理客户端请求失败的情况
                if (apiException.Code > 0) code = apiException.Code;
            }
            else
            {
                sb.AppendLine(ex.ToString());
            }

            if (ex.InnerException != null) sb.AppendLine(ex.InnerException.ToString());

            var requestFeature = HttpContext.Features.Get<IHttpRequestFeature>();
            log.Error($"{requestFeature.Method} {StringUtil.UrlDecode(requestFeature.RawTarget)} \r\n{sb}");

            if(isDevelopment)
            {
                return new JsonResult(new { code, msg, error = ex.StackTrace }) { StatusCode = code };
            }
            else
            {
                return new JsonResult(new { code, msg}) { StatusCode = code };
            }
        }//
    }
}
